package ord2.impl.database;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
import java.util.LinkedList;
import ord2.core.AbstractQuery;
import ord2.core.Result;
import ord2.database.DatabaseConnector;
import ord2.core.Parametric;
import ord2.core.Parameter;

/**
 *
 * @author José Ivan
 * @author Edviges
 */
public final class MysqlDatabaseConnector implements DatabaseConnector, Parametric {

    private Connection con = null;
    
    private LinkedList<Parameter> pars = new LinkedList<Parameter>();
    
    public MysqlDatabaseConnector(Parameter[] pars) throws ClassNotFoundException,
            SQLException {
        
        this.pars.addAll(Arrays.asList(pars));
        
    }
    
    @Override
    public void connect() throws Throwable {

        if (con == null) {
            
            String host = null;
            String port = null;
            String database = null;
            String user = null;
            String pass = null;
            for (Parameter p : this.pars) {

                String name = p.getName();
                if (name.equals("host")) {

                    host = p.getValue();
                } else if (name.equals("port")) {

                    port = p.getValue();
                } else if (name.equals("database")) {

                    database = p.getValue();
                } else if (name.equals("user")) {

                    user = p.getValue();
                } else if (name.equals("password")) {

                    pass = p.getValue();
                }
            }
            Class.forName("com.mysql.jdbc.Driver");
            this.con = DriverManager.getConnection("jdbc:mysql://" + host
                    + ":" + port + "/" + database, user, pass);
        }
    }

    @Override
    public boolean isConnected() {
        
        return this.con != null;
    }

    @Override
    public <Q> Result[] query(AbstractQuery<Q> query) throws Throwable {

        if (this.con == null) {

            return null;
        }
        
        Statement state = this.con.createStatement();
        if (state.execute((String) query.getQuery())) {
        
            return new Result[] {
                            new Result<ResultSet>(state.getResultSet())
                    };
        }
		
        return null;
    }

    @Override
    public void disconnect() throws Throwable {
        
        this.con.close();
        this.con = null;
    }

    @Override
    public Parameter[] getParameters() {
        
        return this.pars.toArray(new Parameter[0]);
    }

    @Override
    public void addParameter(Parameter newParameter) {
        
        this.pars.add(newParameter);
    }

    @Override
    public void removeParameter(Parameter par) {
        
        this.pars.remove(par);
    }
}
